package com.irdstudio.basic.sequence.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.util.DateTool;
import com.irdstudio.basic.framework.core.util.StringUtil;
import com.irdstudio.basic.framework.core.util.TimeUtil;
import com.irdstudio.basic.sequence.service.facade.SequenceService;
import com.irdstudio.basic.sequence.service.impl.support.db.SAutoSeq;
import com.irdstudio.basic.sequence.service.impl.support.db.SequenceDao;

/**
 * 流水号生成
 * @author Cytus_
 *
 */
@Service("sequenceServiceImpl")
public class SequenceServiceImpl implements SequenceService {
	
	public static Map<String, Map<String, String>> templateMap = new ConcurrentHashMap<String, Map<String,String>>();
	
	private static Logger logger = LoggerFactory.getLogger(SequenceServiceImpl.class);
	
	private static String RESET_BY_DAY = "01";//重置频率：按天
	private static String RESET_BY_MONTH = "02";//重置频率：按月
	private static String RESET_BY_YEAR = "03";//重置频率：按年
	//private static String RESET_BY_NEVER = "09";//重置频率：从不
	
	
	@Autowired
	private SequenceDao sequenceDao;
//	@Autowired
//    private PubSysInfoDao pubSysInfoDao;
//	@Autowired
//	private RedisService redisService;
	@Autowired
	private StringRedisTemplate template;
	
	public String getSequence(String seqId, String orgCode, String prdCode, String legalCode, String areaCode) throws Exception {
		String startNum = sequenceDao.getSequenceSerno(seqId);
		List<String> seqNums = this.getSequences(seqId, orgCode, prdCode, legalCode, areaCode, 1, Integer.valueOf(startNum));
		logger.info("流水号ID："+ seqId +"生成的流水号为:"+ seqNums.get(0));
		return seqNums.get(0);
	}

	public List<String> getSequences(String seqId, String orgCode, String prdCode, String legalCode, String areaCode, Integer seqNum) throws Exception {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("seqId", seqId);
		paramMap.put("seqNum", seqNum);
		String startNum = sequenceDao.getBatchSequenceSerno(paramMap);
		List<String> seqNums = this.getSequences(seqId, orgCode, prdCode, legalCode, areaCode, seqNum, Integer.valueOf(startNum));
		logger.info("流水号ID："+ seqId +"生成数量:"+ seqNum +"生成的批量流水号为:"+ seqNums);
		return seqNums;
	}
	
	
	private List<String> getSequences(String seqId, String orgCode, String prdCode, String legalCode, String areaCode, int seqNum, int startNum) {
		Map<String, String> template = templateMap.get(seqId);
		if (Objects.isNull(template) || template.isEmpty()) {
			SAutoSeq sAutoSeq = this.sequenceDao.querySAutoSeqBySeqId(seqId);
			Map<String, String> item = new HashMap<String, String>();
			item.put("sequencestyle", sAutoSeq.getSeqStyle());
			item.put("sequencelength", String.valueOf(sAutoSeq.getSeqLength()));
			templateMap.put(seqId, item);
			template = new HashMap<String, String>();
			template.putAll(item);
		}
		
		String seqStyle = template.get("sequencestyle");
		String seq_length = template.get("sequencelength");
		Calendar calendar = Calendar.getInstance();
		//获取 营业日期
		String openday = TimeUtil.getCurDate();
		String format = "HH:mm:ss";
		String hms = DateTool.getDate(format);
		Date date = DateTool.getDateFromLongStr(openday + " " + hms);
		calendar.setTime(date);
		
		List<String> sequenceList = new ArrayList<String>();
		
		for (int i = 0; i < seqNum; i++) {
			String cur_sernum = numFormatToSeq(Integer.parseInt(seq_length), startNum + i);
			// 替换常用模板参数
			seqStyle = seqStyle.replace("$YEAR$", String.valueOf(calendar.get(Calendar.YEAR)));
			seqStyle = seqStyle.replace("$YE$", String.valueOf(calendar.get(Calendar.YEAR)).substring(2));
			seqStyle = seqStyle.replace("$MONTH$", numFormatToSeq(2, calendar.get(Calendar.MONTH) + 1));
			seqStyle = seqStyle.replace("$DAY$", numFormatToSeq(2, calendar.get(Calendar.DAY_OF_MONTH)));
			seqStyle = seqStyle.replace("$ORG$", StringUtil.nullToEmpty(orgCode));
			seqStyle = seqStyle.replace("$LEGORG$", StringUtil.nullToEmpty(legalCode));
			seqStyle = seqStyle.replace("$AREA$", StringUtil.nullToEmpty(areaCode));
			seqStyle = seqStyle.replace("$PRD$", StringUtil.nullToEmpty(prdCode));
			seqStyle = seqStyle.replace("$SEQ$", cur_sernum);
			seqStyle = seqStyle.replace("$HOUR$", numFormatToSeq(2, calendar.get(Calendar.HOUR_OF_DAY)));
			seqStyle = seqStyle.replace("$MIN$", numFormatToSeq(2, calendar.get(Calendar.MINUTE)));
			seqStyle = seqStyle.replace("$SECOND$", numFormatToSeq(2, calendar.get(Calendar.SECOND)));
			sequenceList.add(seqStyle);
			seqStyle = template.get("sequencestyle");
			
		}
		
		return sequenceList;
	}

	private static String numFormatToSeq(int len, int value) {
		// 如果要改动返回字符串长度，改动maxValue(返回几位数字，则尾数改为几个0)
		if (len <= 0)
			return "";
		// 补足指定长度的0
		StringBuffer seq = new StringBuffer();
		for (int i = 0; i < len; i++) {
			seq.append('0');
		}
		seq.append(value);
	
		return seq.substring(seq.length() - len);
	}

	public String getSequence(String seqId, String orgCode, String prdCode) throws Exception {
		return this.getSequence(seqId, orgCode, prdCode, null, null);
	}

	public List<String> getSequences(String seqId, String orgCode, String prdCode, Integer seqNum) throws Exception {
		return this.getSequences(seqId, orgCode, prdCode, null, null, seqNum);
	}

    @Override
    public int resetSequence(String openday) {
        try {
//            String openday = pubSysInfoDao.getOpenday(BaseConstant.SYS_ID_1001);
            //String openday = TimeUtil.getCurrentDate();
            String lastOpenday = TimeUtil.getYesterday(openday);
            
            //处理每日重置的序列
            logger.info("开始重置频率为【每日重置】的序列......");
            int count = sequenceDao.resetSeq(RESET_BY_DAY, openday, lastOpenday);
            logger.info("重置频率为【每日重置】的序列记录数：" + count);
            
            //处理每月重置的序列
            logger.info("开始重置频率为【每月重置】的序列......");
            if(openday.endsWith("01")) {
                count = sequenceDao.resetSeq(RESET_BY_MONTH, openday, null);
                logger.info("重置频率为【每月重置】的序列记录数：" + count);
            } else {
                logger.error("未到重置频率为【每月重置】的序列的时间！");
            }
            
            //处理每年重置的序列
            logger.info("开始重置频率为【每年重置】的序列......");
            if(openday.endsWith("01-01")) {
                count = sequenceDao.resetSeq(RESET_BY_YEAR, openday, null);
                logger.info("重置频率为【每年重置】的序列记录数：" + count);
            } else {
                logger.error("未到重置频率为【每年重置】的序列的时间！");
            }
            
            //处理最后重置日期为空的数据
            sequenceDao.setLastResetDate(openday);
            //更新营业日期
            template.opsForValue().set(BaseConstant.OPENDAY, openday);
//            redisService.set(BaseConstant.OPENDAY, openday);
        } catch (Exception e) {
            logger.error("重置序列号出现异常！", e);
        }
        return 0;
    }
    
	@Override
    public String getOpenday() {
    	String openday = template.opsForValue().get(BaseConstant.OPENDAY);
//    	if (StringUtils.isEmpty(openday)) {
//    		openday = pubSysInfoDao.getOpenday(BaseConstant.SYS_ID_1001);
//    		template.opsForValue().set(BaseConstant.OPENDAY, openday);
////    		redisService.set(BaseConstant.OPENDAY, openday);
//    	}
    	return openday;
    }
    
}
